package com.dirk.happie.activities;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.dirk.happie.R;
import com.dirk.happie.beans.CompanyBean;
import com.dirk.happie.beans.SettingsBean;
import com.dirk.happie.network.GetSettingsTask;
import com.dirk.happie.network.RequestCompleteListener;
import com.dirk.happie.network.SetFavoritesTask;
import com.dirk.happie.utils.App;
import com.dirk.happie.utils.Availablity;
import com.dirk.happie.utils.Common;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapViewActivity extends FragmentActivity implements LocationListener {
	private App mApp;
	private GoogleMap mMap;

	private List<CompanyBean> companies;
	private ArrayList<LatLng> companyPointList;
	private ArrayList<Marker> newMarkersList;

	private LocationManager locationManager;

	private static final long MIN_TIME = 400;
	private static final float MIN_DISTANCE = 1;

	private GetSettingsTask getSettingsTask = null;
	private SetFavoritesTask setFavoritesTask = null;

	private String longitudeGPS;
	private String latitudeGPS;
	private String provider;

	private Double selectdeCompanyLat = -1d;
	private Double selectedCompanyLng = -1d;
	private boolean showSelectedCompany = false;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_map_view);
		this.mApp = ((App) getApplication());

		
		Intent intent = getIntent();
		if(intent.hasExtra("lat") && intent.hasExtra("lng")){
			selectdeCompanyLat = Double.parseDouble(intent.getStringExtra("lat"));
			selectedCompanyLng = Double.parseDouble(intent.getStringExtra("lng"));
			showSelectedCompany = true;
			System.out.println("showSelectedCompany");
		} else {
			showSelectedCompany = false;
		}
		
		
		locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
		// Define the criteria how to select the location provider -> use
		// default
		Criteria criteria = new Criteria();
		provider = locationManager.getBestProvider(criteria, false);
		// Location location = locationManager.getLastKnownLocation(provider);

		// Initialize the location fields
		companyPointList = new ArrayList<LatLng>();
		newMarkersList = new ArrayList<Marker>();
		Location curLocation = locationManager.getLastKnownLocation(provider);

		companies = mApp.getCompanies();

		for (int i = 0; i < companies.size(); i++) {
			longitudeGPS = companies.get(i).getCompanyPosX();
			latitudeGPS = companies.get(i).getCompanyPosY();
			if (longitudeGPS.equals("")) {
				longitudeGPS = "0";
			}
			if (latitudeGPS.equals("")) {
				latitudeGPS = "0";
			}
			companyPointList.add(new LatLng(Double.parseDouble(longitudeGPS), Double.parseDouble(latitudeGPS)));
		}

		setUpMapIfNeeded();
		try {
			CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(curLocation.getLatitude(), curLocation.getLongitude()), 13.5f);
			if (mMap != null) {
				mMap.animateCamera(cameraUpdate);
			}
		} catch (Exception e) {
			// Couldn't determine location
		}
		// if (location != null) {
		// System.out.println("Provider " + provider + " has been selected.");
		// onLocationChanged(location);
		// } else {
		// System.out.println("Location not available");
		// }
		
		if(!showSelectedCompany)
			locationManager.requestLocationUpdates(provider, MIN_TIME, MIN_DISTANCE, this);
		else {
			LatLng latLng = new LatLng(selectdeCompanyLat, selectedCompanyLng);
			CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17f);
			if (mMap != null) {
				mMap.animateCamera(cameraUpdate);
			}
		}
	}

	@Override
	public View onCreateView(String name, Context context, AttributeSet attrs) {
		// TODO Auto-generated method stub
		return super.onCreateView(name, context, attrs);
	}

	@Override
	protected void onResume() {
		if(!showSelectedCompany)
			locationManager.requestLocationUpdates(provider, MIN_TIME, MIN_DISTANCE, this);
		super.onResume();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_map_view, menu);
		return true;
	}

	private void setUpMapIfNeeded() {
		// Do a null check to confirm that we have not already instantiated the
		// map.
		if (mMap == null) {
			// Try to obtain the map from the SupportMapFragment.
			Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.map);
			SupportMapFragment mapFragment = (SupportMapFragment) fragment;
			mMap = mapFragment.getMap();
			// Check if we were successful in obtaining the map.
			if (mMap != null) {
				setUpMap();
			}
		}
	}

	private void setUpMap() {
		// Hide the zoom controls as the button panel will cover it.
		mMap.getUiSettings().setZoomControlsEnabled(true);

		// Set listeners for marker events. See the bottom of this class for
		// their behavior.
		mMap.setOnMapClickListener(new OnMapClickListener() {

			@Override
			public void onMapClick(LatLng point) {
			}
		});
		for (int i = 0; i < companies.size(); i++) {
			MarkerOptions markerOption = new MarkerOptions().position(companyPointList.get(i)).title(companies.get(i).getCompanyName()).snippet(companies.get(i).getCompanyAddress()).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker));
			// newMarkerOptionsList.get(i).
			Marker marker = mMap.addMarker(markerOption);
			newMarkersList.add(marker);
		}

		mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {

			@Override
			public void onInfoWindowClick(Marker marker) {
				// TODO Auto-generated method stub
				showCompanyDialog(marker);
			}
		});

		mMap.setOnMarkerClickListener(new OnMarkerClickListener() {

			@Override
			public boolean onMarkerClick(Marker marker) {
				// TODO Auto-generated method stub
				showCompanyDialog(marker);
				return false;
			}
		});
		mMap.setMyLocationEnabled(true);
	}

	private Dialog alertDialog;
	String dialogCompanyId;
	int id;

	public void showCompanyDialog(Marker marker) {
		if (alertDialog != null && alertDialog.isShowing()) return;

		alertDialog = new Dialog(this);
		alertDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		alertDialog.setContentView(R.layout.company_dialog);
		alertDialog.setCancelable(true);

		id = Integer.parseInt(marker.getId().substring(1));
		// for (int i = 0; i < companies.size(); i++) {
		// if(companyPointList.get(i).equals(marker.getPosition())){
		// dialogCompanyId = companies.get(i).getCompanyId();
		// }
		// }

		dialogCompanyId = companies.get(id).getCompanyId();

		TextView text = (TextView) alertDialog.findViewById(R.id.dialog_title);
		text.setTextSize(18);
		text.setText(marker.getTitle());

		Button addButton = (Button) alertDialog.findViewById(R.id.add_button);
		addButton.setText(R.string.add_company);
		addButton.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				if (mApp.isLoggedIn()) {
					setFavorite();
				} else {
					Toast.makeText(MapViewActivity.this, getString(R.string.not_logged_in), Toast.LENGTH_SHORT).show();
				}
				alertDialog.cancel();

			}
		});

		Button viewButton = (Button) alertDialog.findViewById(R.id.view_button);
		viewButton.setText(R.string.view_company);
		viewButton.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(MapViewActivity.this, CategoriesActivity.class);
				// intent.putExtra(Keys.KEY_COMPANY_ID, dialogCompanyId);
				mApp.setCompanyLogo(companies.get(id).getCompanyLogo());
				mApp.setCompanyId(companies.get(id).getCompanyId());
				getSettings(companies.get(id).getCompanyId());
				alertDialog.cancel();
				startActivityForResult(intent, 10);
			}
		});
		alertDialog.show();
	}

	private void setFavorite() {
		setFavoritesTask = new SetFavoritesTask(this);

		setFavoritesTask.setRequestCompleteListener(new RequestCompleteListener<String>() {

			@Override
			public void onSuccess(String result) {

				JSONArray jsonArray;
				JSONObject json = null;
				try {
					jsonArray = new JSONArray(result);
					json = jsonArray.getJSONObject(0);
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (json != null && json.has("apimsg")) {
					result = json.optString("apimsg", "");

					for (CompanyBean company : mApp.getCompanies()) {
						if (company.getCompanyId().equals(dialogCompanyId)) {
							// mApp.getFavorites().add(company);
							if (Common.addFavoriteIfExists(mApp.getFavorites(), company)) {
								setResult(500);
								Toast.makeText(MapViewActivity.this, getString(R.string.favorite_added), Toast.LENGTH_SHORT).show();
							} else {
								Toast.makeText(MapViewActivity.this, getString(R.string.favorite_exists), Toast.LENGTH_SHORT).show();
							}
						}
					}

				} else if (json != null && json.has("error")) {
					result = json.optString("error", "");
				}
				// Toast.makeText(MapViewActivity.this, result,
				// Toast.LENGTH_SHORT).show();
			}

			@Override
			public void onFailure(final String message) {
			}
		});

		if (Availablity.isNetworkAvailable(this)) {
			setFavoritesTask.execute(mApp.getUserId(), dialogCompanyId);
		} else {
			Toast.makeText(this, getString(R.string.no_connection), Toast.LENGTH_SHORT).show();
		}

	}

	private void getSettings(String companyId) {

		getSettingsTask = new GetSettingsTask(this);

		getSettingsTask.setRequestCompleteListener(new RequestCompleteListener<List<SettingsBean>>() {

			@Override
			public void onSuccess(List<SettingsBean> result) {
				mApp.setSettings(result.get(0));
			}

			@Override
			public void onFailure(final String message) {
				runOnUiThread(new Runnable() {

					@Override
					public void run() {
						Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
					}
				});

			}
		});

		if (Availablity.isNetworkAvailable(this)) {
			getSettingsTask.execute(companyId);
		} else {
			Toast.makeText(this, getString(R.string.no_connection), Toast.LENGTH_SHORT).show();
		}
	}

	@Override
	protected void onPause() {
		locationManager.removeUpdates(this);
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		if (getSettingsTask != null) {
			getSettingsTask.setRequestCompleteListener(null);
		}
		if (setFavoritesTask != null) {
			setFavoritesTask.setRequestCompleteListener(null);
		}
		super.onDestroy();
	}

	@Override
	public void onLocationChanged(Location location) {
		if(showSelectedCompany){
			return;
		}
		LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
		CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17f);
		if (mMap != null) {
			mMap.animateCamera(cameraUpdate);
		}
		locationManager.removeUpdates(this);
	}

	@Override
	public void onProviderDisabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onProviderEnabled(String provider) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		setResult(resultCode);
		switch (resultCode) {
		case 100:
			finish();
			break;

		// case 200:
		// Intent intent = new Intent(MapViewActivity.this,
		// CategoriesActivity.class);
		// intent.putExtra(Keys.KEY_COMPANY_ID, mApp.getCompanyId());
		// startActivityForResult(intent, 10);
		// finish();
		// break;

		default:
			break;
		}
		super.onActivityResult(requestCode, resultCode, data);
	}
}
